package com.lambkit.core.flow;

import com.lambkit.core.*;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author yangyong(孤竹行)
 */
public class FlowWorkCenter implements IFlowWorkCenter {

    private LifecycleState currentState = LifecycleState.NEW;

    private AppContext appContext;
    /**
     * 流程实例池
     */
    private ConcurrentHashMap<String, FlowInstance> instances = new ConcurrentHashMap<String, FlowInstance>();

    /**
     * 流程节点池
     */
    private ConcurrentHashMap<String, IFlowNode> flowNods = new ConcurrentHashMap<String, IFlowNode>();

    private IFlowNodeFactory flowNodeFactory = new FlowNodeFactory();

    //private final ThreadPoolExecutor jobExecutor;
    private final CronExecutor cronExecutor;

    public FlowWorkCenter(AppContext appContext, long interval) {
        this.appContext = appContext;
        this.appContext.setFlowWorkCenter(this);
        cronExecutor = new CronExecutor(interval, false) {
            @Override
            public void execute() {
                //判断前序节点是否已经执行完成
                Iterator<Map.Entry<String, FlowInstance>> iterator = instances.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, FlowInstance> entry = iterator.next();
                    FlowInstance instance = entry.getValue();
                    if(instance.getCurrentState().equals(LifecycleState.STOPPED)) {
                        iterator.remove();
                    }
                }//while
            }
        };
    }
    @Override
    public LifecycleState getCurrentState() {
        return currentState;
    }

    public void setCurrentState(LifecycleState currentState) {
        this.currentState = currentState;
    }

    @Override
    public void start() throws LifecycleException {
        this.currentState = LifecycleState.STARTING_PREP;
        //启动定时任务，判断前序节点是否完成
        cronExecutor.start();
        cronExecutor.setHeartbeatOpen(true);
    }

    @Override
    public void stop() throws LifecycleException {
        cronExecutor.close();
    }

    public void startFlow(FlowInstance instance) throws LifecycleException {
        instances.put(instance.getFlowContext().getId(), instance);
        instance.start();
    }

    public void register(String name, Class<? extends IFlowNode> clazz) {
        LambkitApp app = Lambkit.app(this.appContext.getName());
        if(app != null) {
            flowNods.put(name, app.getBeanFactory().get(clazz));
        }
    }

    public void register(String name, IFlowNode flowNode) {
        flowNods.put(name, flowNode);
    }

    /////////////////////////////////////////////////
    //get and set

    public AppContext getAppContext() {
        return appContext;
    }

    public void setAppContext(AppContext appContext) {
        this.appContext = appContext;
    }

    public ConcurrentHashMap<String, FlowInstance> getInstances() {
        return instances;
    }

    public void setInstances(ConcurrentHashMap<String, FlowInstance> instances) {
        this.instances = instances;
    }

    public ConcurrentHashMap<String, IFlowNode> getFlowNods() {
        return flowNods;
    }

    public void setFlowNods(ConcurrentHashMap<String, IFlowNode> flowNods) {
        this.flowNods = flowNods;
    }

    public IFlowNodeFactory getFlowNodeFactory() {
        return flowNodeFactory;
    }

    public void setFlowNodeFactory(IFlowNodeFactory flowNodeFactory) {
        this.flowNodeFactory = flowNodeFactory;
    }

    public CronExecutor getCronExecutor() {
        return cronExecutor;
    }
}
